<?php

namespace Demo;

use GuzzleHttp\Client;

class Demo
{
    protected $rsa_public_key;        //对方公钥，加密用
    protected $rsa_private_key;        //己方私钥，解密用

    public function __construct()
    {
        //构造函数，可以通过不同运行环境，载入参�?
        $this->rsa_public_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCKPD4f/3xMjPuHcQSGxPIYZNgF2i0sJhzmKpN3dmzhbKH/1nG+aXUJDhswyitzrI+U0ic/GL/IWB1wQ3noWuLFr8jDSGafenTFiY9c0H9ZAEfqW/oywx95G5JWu5y/ffp4yCmlt8k5kHO/4kE1qnJcGaQlb6/+7t3MPSV5ybmBZwIDAQAB';
        $this->rsa_private_key = 'MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJMr8NnRV7ve7Y5FEBium/TsU0fK5NvzvFpsYxPAQhBXY+EN0Bi2JEg790C1njk9Q3U36u2JBDHAiDIomlgh6wWkJsFn7dghV/fCWSX1VVJ+dRINZy1432fRaJ8GqspvMneBpeLjBe94IwlWKpN+AOR+BNX8QL/uHmfCPlVQXos9AgMBAAECgYAzqbMs434m50UBMmFKKNF6kxNRGnpodBFktLO7FTybu/HF6TFp21a1PMe5IYhfk5AAsBZ6OCUOygWFhhdYZN+5W+dweF3kp1rLE4y5CjwqNlk/g22TAndf9znh/ltHFLvITToqu/eh/34tE1gyNxRbsi1olw/1wv8ZRjM3vtM9QQJBANvNwFq+CJHUyFzkXQB7+ycQFnY8wDq8Uw2Hv9ZMjgIntH7FSlJtdu5mAYPPo6f74slO5tFUMNP7EVppqsjYaNkCQQCraD6iKHo+OIlvvYIKiMXatJGD7N1GNhq5CrhUNPWLHwv/Ih2D3JJdF8IUZOPIJfUxTfM2fZYI+EVdsv6s4RcFAkAGjNYbnighOGcUJZYD6q3sVxVkRqEv3ubWs2HrH/Lna4l8caKqXCq8JfwLkod8/QugFiLYwBqIZqX4vMdjHtfZAkBsAl9dbWZCaPvpxp/4JWGPxDLhz9NLV/KU4bVvkoObq++yUHwKyGYOdVcd5MlIKOsNq5Hzp0Vw14lWVuF2bMxFAkBuNrZksvUULNIaWDKd4rQ6GVzUxXuIZW0ZE6atHYDiXPB4jVAjKRtLxZAV1qH9cr1zNJlcg+RbGYUdF9t4A9n5';
    }


    //支付完成后。这样接收回调报�? �? $data=file_get_contents("php://input");  

    public function test()
    {
        //报文体，array
        $message_body = [
            'page_notify_url'     => 'http://www-2.wg.fuioupay.com:13195/pay_test/callback.jsp',
            'goods_name'         => '衣服',
            'url_link'             => '',
            'ver'                 => '3.0.0',
            'openid'             => '',
            'fee_type'             => 'CNY',
            'mchnt_cd'             => '0001000F0040992',
            'goods_detail'         => '小孩子衣�?',
            'order_date'         => '20230321',
            'back_notify_url'     => 'http://www-2.wg.fuioupay.com:13195/pay_test/callback.jsp',
            'appid'             => '',
            'order_amt'         => '1',
            'pay_type'             => 'AliPayJL',
            'bill_params'         => '',
            'order_id'             => '20230321183330'
        ];
        //生成message
        $message = $this->publicEncryptRsa(json_encode($message_body));
        //发送请求，这里用的Guzzle
        $client = new Client(['verify' => false]);
        $url = 'https://aggpc-test.fuioupay.com/token/order.fuiou';        //接口地址
        $res = $client->request('POST', $url, [
            'json' => [
                'mchnt_cd' => $message_body['mchnt_cd'],                //这里的mchnt_cd要取报文体里面的mchnt_cd
                'message'   => $message
            ]
        ]);
        $result = $res->getBody()->getContents();
        //得到响应，解密数�?
        $decrypted = "";
        if ($result) {
            $result = json_decode($result, true);
            if ($result['resp_code'] == '0000') {
                //只有resp_code�?0000的时候，才有message�?
                $decrypted = $this->privateDecryptRsa($result['message'], $this->rsa_private_key);
                if ($decrypted) {
                    $decrypted = json_decode($decrypted, true);
                }
            }
        }
        //得到解密过后的数�?
        return $decrypted;
    }

    //加密
    private function publicEncryptRsa($plainData = '')
    {
        if (!is_string($plainData)) {
            return null;
        }
        $encrypted = '';
        $partLen = $this->getPublicKenLen() / 8 - 11;
        $plainData = str_split($plainData, $partLen);
        $publicPEMKey = $this->getPublicKey();
        foreach ($plainData as $chunk) {
            $partialEncrypted = '';
            $encryptionOk = openssl_public_encrypt($chunk, $partialEncrypted, $publicPEMKey, OPENSSL_PKCS1_PADDING);
            if ($encryptionOk === false) {
                return false;
            }
            $encrypted .= $partialEncrypted;
        }
        return base64_encode($encrypted);
    }

    private function getPublicKenLen()
    {
        $pub_id = openssl_get_publickey($this->getPublicKey());
        return openssl_pkey_get_details($pub_id)['bits'];
    }

    private function getPublicKey()
    {
        $public_key = $this->rsa_public_key;
        //这里的public_key，是一行的情况，才是这样处理；如果密钥是以文件形式存放且格式已经是换行了的，就需要用另外的方式，参照demo.php里的取法
        $pubic_pem = chunk_split($public_key, 64, "\n");
        $pubic_pem = "-----BEGIN PUBLIC KEY-----\n" . $pubic_pem . "-----END PUBLIC KEY-----\n";
        return $pubic_pem;
    }
    

    //解密
    private function privateDecryptRsa($data = '')
    {
        if (!is_string($data)) {
            return null;
        }
        $decrypted = '';

        $partLen = $this->getPrivateKenLen() / 8;
        $data = str_split(base64_decode($data), $partLen);

        $privatePEMKey = $this->getPrivateKey();

        foreach ($data as $chunk) {
            $partial = '';
            $decryptionOK = openssl_private_decrypt($chunk, $partial, $privatePEMKey, OPENSSL_PKCS1_PADDING);
            if ($decryptionOK === false) {
                return false;
            }
            $decrypted .= $partial;
        }
        return $decrypted;
    }

    private function getPrivateKenLen()
    {
        $pub_id = openssl_get_privatekey($this->getPrivateKey());
        return openssl_pkey_get_details($pub_id)['bits'];
    }

    private function getPrivateKey()
    {
        //这里的private_key，是一行的情况，才是这样处理；如果密钥是以文件形式存放且格式已经是换行了的，就需要用另外的方式，参照demo.php里的取法
        $private_key = $this->rsa_private_key;
        $private_pem = chunk_split($private_key, 64, "\n");
        $private_pem = "-----BEGIN PRIVATE KEY-----\n" . $private_pem . "-----END PRIVATE KEY-----\n";
        return $private_pem;
    }
}
